<?php

/**
 * user表的数据层操作文件
 *
 * @author banyanCheung <banyan@ibos.com.cn>
 * @link http://www.ibos.com.cn/
 * @copyright Copyright &copy; 2012-2013 IBOS Inc
 */
/**
 * user表的数据层操作类
 *
 * @package application.modules.user.model
 * @version $Id: User.php 7505 2016-07-07 07:37:58Z gzhyj $
 * @author banyanCheung <banyan@ibos.com.cn>
 */

namespace application\modules\user\model;

use application\core\model\Model;
use application\core\utils as util;
use application\core\utils\Env;
use application\core\utils\IBOS;
use application\modules\department\model\DepartmentRelated;
use application\modules\department\model\Department;
use application\modules\position\model\PositionRelated;
use application\modules\role\model\RoleRelated;
use application\modules\user\utils\User as UserUtil;

class User extends Model {

    const USER_STATUS_ABANDONED = 2;
    const USER_STATUS_LOCKED = 1;
    const USER_STATUS_NORMAL = 0;

    public static function model($className = __CLASS__) {
        return parent::model($className);
    }

    public function tableName() {
        return '{{user}}';
    }

    //以下大量函数被重新改写，原因是AR在处理复杂的业务时效率不高，应该用DAO代替
    //AR使用场景只是为了提高代码编写效率用的
    //参见：
    //作者本人对于AR的效率回复：http://www.yiiframework.com/forum/index.php/topic/16597-yii%E7%9A%84ar%E7%9C%9F%E7%9A%84%E8%83%BD%E7%94%A8%E4%B9%88%EF%BC%9F/
    public $select = '*';
    public $limit = NULL;
    public $offset = NULL;
    public $leftJoin = NULL;
    public $pre = '';

    /**
     * 用以设置select值，如果需要前缀，也直接加，如：' `u`.`uid`,`u`.`username` '
     * @param string $select
     */
    public function setSelect($select) {
        $this->select = $select;
    }

    public function setLimit($limit) {
        $this->limit = $limit;
    }

    public function setOffset($offset) {
        $this->offset = $offset;
    }

    public function setLeftJoin($table, $join) {
        $this->leftJoin = array($table, $join);
    }

    public function setPre($pre) {
        $this->pre = $pre;
    }

    /**
     * 用以重置DAO的一些参数，目前只有一个select
     */
    public function afterQuery() {
        $this->select = '*';
        $this->limit = NULL;
        $this->offset = NULL;
        $this->leftJoin = NULL;
        $this->pre = '';
    }

    //--------------------------builder condition------------------builder的条件
    //约定：
    //用下划线命名的函数表示用来快速格式化一些SQL语句的函数
    //X后缀表示可以支持数组或者逗号分割的字符串（简称逗号字符串）
    //返回值是yii可能支持的一些SQL格式，比如条件的话，可以支持数组和字符串
    //尽可能条件尽可能具体，不要太复杂
    /**
     * 用以生成uid的FIND_IN_SET语句，结果可能是FIND_IN_SET( `uid`,'1,2,3' )
     * 如果需要生成FIND_IN_SET( '1,2,3', `uid` )，建议写一个find_in_set_uid函数
     * @param mixed $uidX 支持uid的数组和逗号字符串
     * @param string $pre 表简称，一般直接拿除去前缀的表的首字母，比如ibos_user_profile这里定义成up
     * @return string 格式化后的condition语句。后面也是一样的，yii支持数组，所以这样的格式化函数也可以返回数组，只是这个是字符串
     */
    public function uid_find_in_set($uidX, $pre = '') {
        $preString = empty($pre) ? $pre : '`' . $pre . '`.';
        $uidString = is_array($uidX) ? implode(',', $uidX) : $uidX;
        return " FIND_IN_SET( {$preString}`uid`, '{$uidString}') ";
    }

    /**
     * 用户状态非禁用的条件
     * @param string $pre 表简称
     * @return string
     */
    public function status_not_disabled($pre = '') {
        $preString = empty($pre) ? $pre : '`' . $pre . '`.';
        $abandoned = self::USER_STATUS_ABANDONED;
        return " {$preString}`status` != '{$abandoned}' ";
    }

    /**
     * uid等于？
     * @param integer $uid uid
     * @param string $pre 表简写
     * @return string
     */
    public function uid_eq($uid, $pre = '') {
        $preString = empty($pre) ? $pre : '`' . $pre . '`.';
        return "{$preString}`uid` = '{$uid}' ";
    }

    //--------------------------builder condition end-------------
    //--------------------------new function-----------------------新一批的函数，旧的函数需要被优化的
    //一些重写的函数，约定
    //indexBy表示返回的数组的键是By后面的值，比如findUserIndexByUid表示查询出来的二维user数组，键是uid
    //第一个参数尽量是By后面的字段，比如上面就是uid，而且尽可能数组和字符串都支持
    //如果这个字段默认值是NULL，表示有可能查询表里的所有的该字段的值
    //
    /**
     * 获取user表的数据，并且以uid作为数组的键
     * @param mixed $uidX uid数组或者字符串
     * @param boolean $returnDisabled 是否返回禁用用户，默认不
     * @param mixed $extraCondition 额外的条件
     * @return array
     */
    public function findUserIndexByUid($uidX = NULL, $returnDisabled = false, $extraCondition = '') {
        if (empty($uidX) && NULL !== $uidX) {
            return array();
        }
        $userArray = $this->findUserByUid($uidX, $returnDisabled, $extraCondition);
        $return = array();
        if (!empty($userArray)) {
            foreach ($userArray as $user) {
                $return[$user['uid']] = $user;
            }
        }
        return $return;
    }

    /**
     * 获取user表的数据
     * @param mixed $uidX uid数组或者字符串
     * @param boolean $returnDisabled 是否返回禁用用户，默认false，只返回非禁用用户
     * @param mixed $extraCondition 额外的条件
     * @return array
     */
    public function findUserByUid($uidX = NULL, $returnDisabled = false, $extraCondition = '') {
        if (empty($uidX) && NULL !== $uidX) {
            return array();
        }
        $query = IBOS::app()->db->createCommand()
            ->select($this->select)
            ->from($this->tableName());
        $conditionArray = array(
            !empty($uidX) ? $this->uid_find_in_set($uidX, $this->pre) : 1,
            false === $returnDisabled ? $this->status_not_disabled($this->pre) : 1,
            !empty($extraCondition) ? $extraCondition : 1,
        );
        $condition = array_filter($conditionArray, function ($cond) {
            if ($cond != 1) {
                return true;
            }
        });
        $query->where(implode(' AND ', $condition));
        NULL !== $this->limit && $query->limit($this->limit);
        NULL !== $this->offset && $query->offset($this->offset);
        NULL !== $this->leftJoin && $query->leftJoin($this->leftJoin[0], $this->leftJoin[1]);
        $userArray = $query->queryAll();
        $this->afterQuery();
        return $userArray;
    }

    /**
     * 根据批量uid获取批量真实姓名，uid为数组的键
     * @param mixed $uidX
     * @return array
     */
    public function findRealnameIndexByUid($uidX) {
        $realName = IBOS::app()->db->createCommand()
            ->select('uid,realname')
            ->from($this->tableName())
            ->where($this->uid_find_in_set($uidX))
            ->queryAll();
        $return = array();
        if (!empty($realName)) {
            foreach ($realName as $name) {
                $return[$name['uid']] = $name['realname'];
            }
        }
        return $return;
    }

    /**
     * 获取所有的uid
     * @param boolean $returnDisabled 是否禁用用户一起返回
     * @return array
     */
    public function fetchUidA($returnDisabled = false) {
        $condition = $returnDisabled ? 1 : $this->status_not_disabled();
        $uidA = IBOS::app()->db->createCommand()
            ->select('uid')
            ->from($this->tableName())
            ->where($condition)
            ->queryColumn();
        return $uidA;
    }

    /**
     * 根据批量uid获取批量真实姓名和电话，uid为数组的键
     * @param mixed $uidX
     * @return array
     */
    public function findThreeByUid($uidX) {
        $return = IBOS::app()->db->createCommand()
            ->select('uid,realname,mobile,deptid')
            ->from($this->tableName())
            ->where($this->uid_find_in_set($uidX))
            ->queryAll();
        return $return;
    }

    /**
     * 处理一组uid，将禁用的uid去除掉
     * @param mix $uidX uid一维数组或者逗号隔开的字符串
     * @return array
     */
    public function findNotDisabledUid($uidX) {
        $uidArray = IBOS::app()->db->createCommand()
            ->select('uid')
            ->from($this->tableName())
            ->where(array(
                'AND',
                $this->uid_find_in_set($uidX),
                $this->status_not_disabled(),
            ))
            ->queryColumn();
        return $uidArray;
    }

    /**
     * 获得某种状态的所有用户数组
     * @param integer $status 状态（0：启用 1：锁定 2：禁用）
     * @return type
     */
    public function fetchAllUidsByStatus($status) {
        $uidArray = IBOS::app()->db->createCommand()
            ->select('uid')
            ->from($this->tableName())
            ->where(" `status` = '{$status}' ")
            ->queryColumn();
        return $uidArray;
    }

    /**
     * 获取某个uid的所有部门
     * @param integer $uid uid
     * @param boolean $onlyRelated 是否只返回关联数据，默认false，返回包括主部门
     * @return array
     */
    public function findAllDeptidByUid($uid, $onlyRelated = false) {
        $main = NULL;
        if (false === $onlyRelated) {
            $main = IBOS::app()->db->createCommand()
                ->select('deptid')
                ->from($this->tableName())
                ->where($this->uid_eq($uid))
                ->queryScalar();
        }
        $related = IBOS::app()->db->createCommand()
            ->select('deptid')
            ->from(DepartmentRelated::model()->tableName())
            ->where($this->uid_eq($uid))
            ->queryColumn();

        return array_unique(array_merge($related, array($main)));
    }

    /**
     * 获取某个uid的所有岗位
     * @param integer $uid uid
     * @param boolean $onlyRelated 是否只返回关联数据，默认false，返回包括主岗位
     * @return array
     */
    public function findAllPositionidByUid($uid, $onlyRelated = false) {
        $main = NULL;
        if (false === $onlyRelated) {
            $main = IBOS::app()->db->createCommand()
                ->select('positionid')
                ->from($this->tableName())
                ->where($this->uid_eq($uid))
                ->queryScalar();
        }
        $related = IBOS::app()->db->createCommand()
            ->select('positionid')
            ->from(PositionRelated::model()->tableName())
            ->where($this->uid_eq($uid))
            ->queryColumn();

        return array_unique(array_merge($related, array($main)));
    }

    /**
     * 获取某个uid的所有角色
     * @param integer $uid uid
     * @param boolean $onlyRelated 是否只返回关联数据，默认false，返回包括主角色
     * @return array
     */
    public function findAllRoleidByUid($uid, $onlyRelated = false) {
        $main = NULL;
        if (false === $onlyRelated) {
            $main = IBOS::app()->db->createCommand()
                ->select('roleid')
                ->from($this->tableName())
                ->where($this->uid_eq($uid))
                ->queryScalar();
        }
        $related = IBOS::app()->db->createCommand()
            ->select('roleid')
            ->from(RoleRelated::model()->tableName())
            ->where($this->uid_eq($uid))
            ->queryColumn();

        return array_unique(array_merge($related, array($main)));
    }

    /**
     * 根据批量uid获取部门id，uid作为键
     * @param mixed $uidX uid数组或者逗号字符串，默认NULL，表示返回所有uid的
     * @return array 返回关联和主要部门id
     */
    public function findDeptidIndexByUid($uidX = NULL) {
        $condition = 1;
        if (NULL !== $uidX) {
            $condition = $this->uid_find_in_set($uidX);
        }
        $deptRelated = IBOS::app()->db->createCommand()
            ->select('uid,deptid')
            ->from(DepartmentRelated::model()->tableName())
            ->where($condition)
            ->queryAll();
        $deptMain = IBOS::app()->db->createCommand()
            ->select('uid,deptid')
            ->from($this->tableName())
            ->where($condition)
            ->queryAll();
        $return = $relatedArray = array();
        foreach ($deptRelated as $related) {
            $relatedArray[$related['uid']][] = $related['deptid'];
        }
        foreach ($deptMain as $main) {
            $return[$main['uid']] = array(
                'main' => $main['deptid'],
                'related' => !empty($relatedArray[$main['uid']]) ? $relatedArray[$main['uid']] : array(),
            );
        }
        return $return;
    }

    /**
     * 根据批量uid获取岗位id，uid作为键
     * @param mixed $uidX uid数组或者逗号字符串，默认NULL，表示返回所有uid的
     * @return array 返回关联和主要岗位id
     */
    public function findPositionidIndexByUid($uidX = NULL) {
        $condition = 1;
        if (NULL !== $uidX) {
            $condition = $this->uid_find_in_set($uidX);
        }
        $PositionRelated = IBOS::app()->db->createCommand()
            ->select('uid,positionid')
            ->from(PositionRelated::model()->tableName())
            ->where($condition)
            ->queryAll();
        $positionMain = IBOS::app()->db->createCommand()
            ->select('uid,positionid')
            ->from($this->tableName())
            ->where($condition)
            ->queryAll();
        $return = $relatedArray = array();
        foreach ($PositionRelated as $related) {
            $relatedArray[$related['uid']][] = $related['positionid'];
        }
        foreach ($positionMain as $main) {
            $return[$main['uid']] = array(
                'main' => $main['positionid'],
                'related' => !empty($relatedArray[$main['uid']]) ? $relatedArray[$main['uid']] : array(),
            );
        }
        return $return;
    }

    /**
     * 根据批量uid获取角色id，uid作为键
     * @param mixed $uidX uid数组或者逗号字符串，默认NULL，表示返回所有uid的
     * @return array 返回关联和主要角色id
     */
    public function findRoleidIndexByUid($uidX = NULL) {
        $condition = 1;
        if (NULL !== $uidX) {
            $condition = $this->uid_find_in_set($uidX);
        }
        $roleRelated = IBOS::app()->db->createCommand()
            ->select('uid,roleid')
            ->from(RoleRelated::model()->tableName())
            ->where($condition)
            ->queryAll();
        $roleMain = IBOS::app()->db->createCommand()
            ->select('uid,roleid')
            ->from($this->tableName())
            ->where($condition)
            ->queryAll();
        $return = $relatedArray = array();
        foreach ($roleRelated as $related) {
            $relatedArray[$related['uid']][] = $related['roleid'];
        }
        foreach ($roleMain as $main) {
            $return[$main['uid']] = array(
                'main' => $main['roleid'],
                'related' => !empty($relatedArray[$main['uid']]) ? $relatedArray[$main['uid']] : array(),
            );
        }
        return $return;
    }

    /**
     * 通过uid取得该用户所有下属id
     * @param integer $uid
     * @return array
     */
    public function fetchSubUidByUid($uid) {
        $uidArray = IBOS::app()->db->createCommand()
            ->select('uid')
            ->from($this->tableName())
            ->where(array(
                'AND',
                $this->status_not_disabled(),
                " `upuid` ='{$uid}' "
            ))
            ->queryColumn();
        return $uidArray;
    }

    /**
     * 根据用户真实姓名查找用户信息，如果有重复，则只拿第一个查出来的
     * @param string $name 真实姓名
     * @return array 用户数据
     */
    public function findByRealname($name) {
        $user = IBOS::app()->db->createCommand()
            ->select()
            ->from($this->tableName())
            ->where(" `realname` = ':name' ", array(':name' => $name))
            ->queryScalar();
        return $user;
    }

    /**
     * 根据多个真实姓名获取uid数组
     * @param mixed $realnameX 真实姓名的数组或者逗号字符串
     * @return array
     */
    public function findUidByRealnameX($realnameX) {
        $realnameString = is_array($realnameX) ? implode(',', $realnameX) : $realnameX;
        $uidArray = IBOS::app()->db->createCommand()
            ->select('uid')
            ->from($this->tableName())
            ->where(" FIND_IN_SET( `realname`, '{$realnameString}') ")
            ->queryColumn();
        return $uidArray;
    }

	/**
	 * 根据用户id查找一条用户数据，该函数将获取用户的详细信息
	 * @param integer $uid
	 * @return array
	 */
	public function fetchByUid( $uid ) {
		$user = UserUtil::wrapUserInfo( $uid,true,true );
		return !empty( $user[$uid] ) ? $user[$uid] : array();
	}

	/**
	 * 根据用户id数组查找多条用户数据，该函数将获取用户的详细信息。uid作为键
	 * @param mixed $uidX uid的数组或者逗号字符串
	 * @return array
	 */
	public function fetchAllByUids( $uidX = NULL, $returnDisabled = true ) {
		if ( NULL !== $uidX && empty($uidX)) {
			return false;
		} else {
			return UserUtil::wrapUserInfo( $uidX, $returnDisabled );
		}
	}

    /**
     * 根据UID查找用户真实姓名
     * @param integer $uid
     * @return string
     */
    public function fetchRealnameByUid($uid) {
        $realname = IBOS::app()->db->createCommand()
            ->select('realname')
            ->from($this->tableName())
            ->where($this->uid_eq($uid))
            ->queryScalar();
        return $realname;
    }

    /**
     * 查找用户真实姓名，返回$glue分隔的字符串格式
     * @param mixed $uidX 用户ID数组或=逗号分隔ID串
     * @param string $glue 分隔符
     * @return string
     */
    public function fetchRealnamesByUids($uidX, $glue = ',') {
        $realnameArray = IBOS::app()->db->createCommand()
            ->select('realname')
            ->from($this->tableName())
            ->where($this->uid_find_in_set($uidX))
            ->queryColumn();
        return implode($glue, $realnameArray);
    }

    /**
     * 检查能否禁用或者锁定一批用户，如果禁用了之后一个管理员都没有，就禁止禁用这些uid
     * @param type $uidX
     */
    public function checkCanDisabled($uidX) {
        $uidArray = is_array($uidX) ? $uidX : explode(',', $uidX);
        $adminArray = IBOS::app()->db->createCommand()
            ->select('uid')
            ->from($this->tableName())
            ->where(" isadministrator = 1 ")
            ->queryColumn();
        $isEmpty = array_diff($adminArray, $uidArray);
        return !empty($isEmpty);
    }

    //--------------------------new function end------------------
    /**
     * 检查用户名是否存在
     * @param string $name
     * @return boolean
     */
    public function userNameExists($name) {
        $user = $this->fetch('username = :name', array(':name' => $name));
        if (!empty($user)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 检查唯一字段
     * @param 需要插入的用户 $data
     * @param 唯一字段的配置 $uniqueConfig ，格式：key对应数据表里的字段，value对应这个字段的解释
     */
    public function checkUnique($data, $uniqueConfig = array('mobile' => '手机号', 'username' => '用户名',)) {
        $arr1 = $arr2 = array();
        foreach ($uniqueConfig as $k => $v) {
            if (!empty($data[$k])) {
                $arr1[] = $k . '=:' . $k;
                $arr2[':' . $k] = $data[$k];
            }
        }

        $str = implode(' or ', $arr1);
        if (isset($data['uid'])) {
            $con = ' and uid != :uid';
            $arr2[':uid'] = $data['uid'];
            $str = '(' . $str . ')' . $con;
        }
        $res = $this->fetch($str, $arr2);
        if (!empty($res)) {
            //todo:更好的显示方式
            Env::iExit('请检查：' . implode(',', $uniqueConfig) . '中是否有重复的用户');
        }
    }

    /**
     * 查找部门内符合条件的人
     */
    public function fetchAllFitDeptUser($dept) {
        $uidArray = util\IBOS::app()->db->createCommand()
            ->select('u.uid')
            ->from('{{user}} u')
            ->leftJoin('{{department_related}} dr', 'u.uid = dr.uid')
            ->where(array(
                'AND',
                $this->status_not_disabled('u'),
                array(
                    'OR',
                    Department::model()->deptid_find_in_set($dept, 'u'),
                    Department::model()->deptid_find_in_set($dept, 'dr'),
                ),
            ))
            ->queryColumn();
        return $this->fetchAllByUids($uidArray);
    }

    /**
     * 没设部门主管的情况下查找其他有权限的人
     */
    public function fetchAllOtherManager($dept) {
        $list = util\IBOS::app()->db->createCommand()
            ->select('u.uid')
            ->from('{{user}} u')
            ->leftJoin('{{department_related}} dr', 'u.uid = dr.uid')
            ->where($this->status_not_disabled('u')
                . " AND ((FIND_IN_SET(u.deptid,'{$dept}') OR FIND_IN_SET(dr.deptid,'{$dept}')))")
            ->queryAll();
        return $list;
    }

    /**
     * 根据岗位id获取所有uid
     * @param integer $posid
     * @param boolean $returnDisabled 是否禁用用户一起返回
     * @return string
     * @author Ring
     * @refactor banyan
     */
    public function fetchUidByPosId($positionid, $returnDisabled = true, $related = false) {
        static $positionidArray = array();
        if (!isset($positionidArray[$positionid])) :
            $condition = " `u`.`positionid`= '{$positionid}' ";
            $query = IBOS::app()->db->createCommand();
            if (true === $related):
                $query = $query->leftJoin(PositionRelated::model()->tableName() . ' prpr'//自行百度prpr，我真的没有想歪
                    , " `prpr`.`uid` = `u`.`uid` ");
                $condition = array(
                    'OR',
                    $condition,
                    " `prpr`.`positionid`= '{$positionid}' ",
                );
            endif;
            if (true === $returnDisabled):
                $condition = array(
                    'AND',
                    $condition,
                    $this->status_not_disabled('u'),
                );
            endif;
            $uidArray = $query->selectDistinct('u.uid')
                ->from($this->tableName() . ' u')
                ->where($condition)
                ->queryColumn();
            $positionidArray[$positionid] = $uidArray;
        endif;
        return $positionidArray;
    }

    /**
     * 根据角色id获取所有uid
     * @param integer $roleid
     * @param boolean $returnDisabled 是否禁用用户一起返回
     * @param boolean $related 是否返回辅助角色
     * @return array
     */
    public function fetchUidByRoleId($roleid, $returnDisabled = true, $related = false) {
        if (!isset($RoleidArray[$roleid])) {
            $condition = " `u`.`roleid` = '{$roleid}'";
            $query = IBOS::app()->db->createCommand();
            if (true === $related):
                $query = $query->leftJoin(RoleRelated::model()->tableName() . ' rr'
                    , " `rr`.`uid` = `u`.`uid` ");
                $condition = array(
                    'OR',
                    $condition,
                    " `rr`.`roleid` = '{$roleid}' ",
                );
            endif;
            if (true === $returnDisabled):
                $condition = array(
                    'AND',
                    $condition,
                    $this->status_not_disabled('u'),
                );
            endif;
            $uidArray = $query->selectDistinct('u.uid')
                ->from($this->tableName() . ' u')
                ->where($condition)
                ->queryColumn();
            $RoleidArray[$roleid] = $uidArray;
        }
        return $RoleidArray[$roleid];
    }

	/**
	 * 根据角色 ID 列表获取对应的用户 ID 数组
	 * @param  string|array $roleids 角色列表
	 * @param  boolean $returnDisabled 是否去除被禁用的用户 ID
	 * @param  boolean $related 是否关联用户角色关系表数据
	 * @return
	 */
	public function fetchAllUidByRoleids( $roleids, $returnDisabled = true, $related = false ) {
		$roleids = is_array( $roleids ) ? implode( ',', $roleids ) : $roleids;
		$condition = " FIND_IN_SET( `u`.`roleid`, '{$roleids}' ) ";
		$query = Ibos::app()->db->createCommand();
		if ( true === $related ):
			$query = $query->leftJoin( RoleRelated::model()->tableName() . ' rr'
					, " `rr`.`uid` = `u`.`uid` " );
			$condition = array(
				'OR',
				$condition,
				" FIND_IN_SET( `rr`.`roleid`, '{$roleids}' ) ",
			);
		endif;
		if ( false === $returnDisabled ):
			$condition = array(
				'AND',
				$condition,
				" `u`.`status` != '" . self::USER_STATUS_ABANDONED . "'",
			);
		endif;
		$uidArray = $query->selectDistinct( 'u.uid' )
				->from( $this->tableName() . ' u' )
				->where( $condition )
				->queryColumn();
		return $uidArray;
	}

	/**
	 * 根据多个岗位id获取所有uid
	 * @param mix $positionids
	 * @param boolean $returnDisabled 是否禁用用户一起返回
	 * @param boolean $related 是否返回辅助岗位
	 * @return array
	 */
	public function fetchAllUidByPositionIds( $positionids, $returnDisabled = true, $related = false ) {
		$positionString = is_array( $positionids ) ? implode( ',', $positionids ) : $positionids;
		$condition = " FIND_IN_SET(`u`.`positionid`, '{$positionString}') ";
		$query = Ibos::app()->db->createCommand();
		if ( true === $related ):
			$query = $query->leftJoin( PositionRelated::model()->tableName() . ' prpr'//自行百度prpr，我真的没有想歪
					, " `prpr`.`uid` = `u`.`uid` " );
			$condition = array(
				'OR',
				$condition,
				" FIND_IN_SET(`prpr`.`positionid`, '{$positionString}') ",
			);
		endif;
		if ( false === $returnDisabled ):
			$condition = array(
				'AND',
				$condition,
				" `u`.`status` != '" . self::USER_STATUS_ABANDONED . "'",
			);
		endif;
		$uidArray = $query->selectDistinct( 'u.uid' )
				->from( $this->tableName() . ' u' )
				->where( $condition )
				->queryColumn();
		return $uidArray;
	}

    /**
     * 根据部门id获取所有uid
     * @param integer $deptid
     * @param boolean $returnDisabled 是否禁用用户一起返回
     * @param boolean $related 是否返回辅助部门的用户
     * @return array
     */
    public function fetchAllUidByDeptid($deptid, $returnDisabled = true, $related = false) {
        static $deptidArray = array();
        if (!isset($deptidArray[$deptid])) {
            $condition = " `u`.`deptid` = '{$deptid}'";
            $query = IBOS::app()->db->createCommand();
            if (true === $related):
                $query = $query->leftJoin(DepartmentRelated::model()->tableName() . ' dr'
                    , " `dr`.`uid` = `u`.`uid` ");
                $condition = array(
                    'OR',
                    $condition,
                    " `dr`.`deptid` = '{$deptid}'",
                );
            endif;
            if (true === $returnDisabled):
                $condition = array(
                    'AND',
                    $condition,
                    " `u`.`status` != '" . self::USER_STATUS_ABANDONED . "'",
                );
            endif;
            $uidArray = $query->selectDistinct('u.uid')
                ->from($this->tableName() . ' u')
                ->where($condition)
                ->queryColumn();
            $deptidArray[$deptid] = $uidArray;
        }
        return $deptidArray[$deptid];
    }

	/**
	 * 根据多个部门id获取所有uid
	 * @param mix $deptIds
	 * @param boolean $returnDisabled 是否禁用用户一起返回
	 * @return array
	 */
	public function fetchAllUidByDeptids( $deptids, $returnDisabled = true, $related = false ) {
		$deptidString = is_array( $deptids ) ? implode( ',', $deptids ) : $deptids;
		$condition = " FIND_IN_SET(`u`.`deptid`, '{$deptidString}') ";
		$query = Ibos::app()->db->createCommand();
		if ( true === $related ):
			$query = $query->leftJoin( DepartmentRelated::model()->tableName() . ' dr'
					, " `dr`.`uid` = `u`.`uid` " );
			$condition = array(
				'OR',
				$condition,
				" FIND_IN_SET(`dr`.`deptid`, '{$deptidString}') ",
			);
		endif;
		if ( false === $returnDisabled ):
			$condition = array(
				'AND',
				$condition,
				" `u`.`status` != '" . self::USER_STATUS_ABANDONED . "'",
			);
		endif;
		$uidArray = $query->selectDistinct( 'u.uid' )
				->from( $this->tableName() . ' u' )
				->where( $condition )
				->queryColumn();
		return $uidArray;
	}

    /**
     * 查找所有用户UID以积分高低排序
     * @return array
     */
    public function fetchAllCredit() {
        $uid = IBOS::app()->db->createCommand()
            ->select('uid')
            ->from($this->tableName())
            ->where(" `status` != 2 ")
            ->order(' credits DESC ')
            ->queryColumn();
        return !empty($uid) ? $uid : array();
    }

    /**
     * 根据部门ID,类型查找数据
     * @param string $type 查询类型
     * @param integer $limit
     * @param integer $offset
     * @return array
     */
    public function fetchAllByDeptIdType($deptId, $type, $limit, $offset) {
        $condition = array(
            'condition' => $this->getConditionByDeptIdType($deptId, $type),
            'order' => 'createtime DESC',
            'limit' => $limit,
            'offset' => $offset
        );
        return $this->fetchAll($condition);
    }

    /**
     * 批量更新用户信息
     * @param mixed $uids 用户ID字符串或数组
     * @param array $attributes 要更新的值
     * @return integer
     */
    public function updateByUids($uidX, $attributes = array()) {
        $counter = $this->updateAll($attributes, $this->uid_find_in_set($uidX));
        return $counter;
    }

    /**
     * 按UID更新用户信息
     * @param type $uid
     * @param type $attributes
     * @return type
     */
    public function updateByUid($uid, $attributes) {
        $counter = $this->updateByPk($uid, $attributes);
        return $counter;
    }

    /**
     * 根据部门ID,类型统计人数
     * @param string $type 查询类型
     * @return integer
     */
    public function countByDeptIdType($deptId, $type) {
        return $this->count(array('condition' => $this->getConditionByDeptIdType($deptId, $type)));
    }

    /**
     * 根据类型获取条件语句
     * @param string $type 查询类型
     * @return string SQL where 字段
     */
    public function getConditionByDeptIdType($deptId, $type) {
        $condition = $deptId ? "`deptid` = {$deptId} AND " : '';
        switch ($type) {
            case 'enabled':
                $condition .= '`status` = 0';
                break;
            case 'lock':
                $condition .= '`status` = 1';
                break;
            case 'disabled' :
                $condition .= '`status` = 2';
                break;
            default:
                $condition .= '1';
                break;
        }
        return $condition;
    }

    /**
     * 通过uid取得该用户所有下属(日程模块和日志模块用到)
     * @param integer $uid
     * @return array
     */
    public function fetchSubByPk($uid, $limitCondition = '') {
        $records = $this->fetchAll(array(
            'select' => 'uid, username, deptid, upuid, realname',
            'condition' => 'upuid=:upuid AND status != 2' . $limitCondition,
            'params' => array(':upuid' => $uid)
        ));
        $userArr = array();
        foreach ($records as $user) {
            $userArr[] = $user;
        }
        return $userArr;
    }

    /**
     * 根据用户id获取头像
     * @param integer $uid 用户id
     * @param string $size 大小标识，b大，m中，s小
     * @return string
     */
    public function fetchAvatarByUid($uid, $size = 'm') {
        $user = $this->fetchByUid($uid);
        if (empty($user)) {
            return '';
        }
        if ($size == 'b') {
            // 大头像
            $avatar = $user['avatar_big'];
        } elseif ($size == 's') {
            // 小头像
            $avatar = $user['avatar_small'];
        } else {
            // 中头像
            $avatar = $user['avatar_middle'];
        }
        return $avatar;
    }

    /**
     * 根据岗位ID统计用户数（忽略辅助岗位）
     * @param integer $positionid
     * @return integer
     */
    public function countNumsByPositionId($positionid) {
        return User::model()->count('positionid = :positionid AND status != 2', array(':positionid' => $positionid));
    }

    /**
     * 根据角色ID统计用户数（忽略辅助角色）
     * @param integer $roleId
     * @return integer
     */
    public function countNumsByRoleId($roleId) {
        return User::model()->count('roleid = :roleid AND status != 2', array(':roleid' => $roleId));
    }

    /**
     * 根据某个条件更新用户信息
     * @param mixed $uidX 用户ID字符串或数组
     * @param array $attributes 要更新字段值
     * @return integer
     * @author Sam 2015-08-21 <gzxgs@ibos.com.cn>
     */
    public function updateByConditions($uidX, $attributes = array(), $condition = "") {
        $cond = array(
            'AND',
            $this->uid_find_in_set($uidX),
            empty($condition) ? 1 : $condition,
        );
        return $this->updateAll($attributes, $cond);
    }

    public function checkIsExistByMobile($mobile) {
        $result = $this->fetch('mobile  = :mobile', array(':mobile' => $mobile));
        return !empty($result) ? true : false;
    }

    /**
     * 根据用户状态批量获取用户信息
     * @param  integer|array $status 用户状态 0,1,2 可以是数组也可以是整型
     * @return array         用户信息数组
     */
    public function fetchAllByStatus($status) {
        if (is_array($status)) {
            $status = implode(',', $status);
        }
        $result = $this->fetchAll(array(
            'condition' => "FIND_IN_SET( status, ':status' )",
            'params' => array(':status' => $status),
        ));
        return !empty($result) ? TRUE : FALSE;
    }

    /**
     *查询未跟酷办公关联的用户id
     * @param  integer $limit
     * @return array  用户uid数组
     */
    public function fetchUnbind($limit = NULL) {
        $query = util\IBOS::app()->db->createCommand()
            ->select('u.uid')
            ->from('{{user}} u')
            ->leftJoin('{{user_binding}} b', 'u.uid = b.uid')
            ->where("b.uid is null");
        if ($limit) {
            $query = $query->limit($limit);
        }
        $list = $query->queryColumn();

        return $list;
    }

    /**
     *查询跟酷办公关联但已禁用的用户id
     */
    public function fetchDeletebind() {
        $list = util\IBOS::app()->db->createCommand()
            ->select('u.uid')
            ->from('{{user}} u')
            ->leftJoin('{{user_binding}} b', 'u.uid = b.uid')
            ->where("u.status =" . self::USER_STATUS_ABANDONED . " and app='co' ")->queryColumn();
        return $list;
    }


    /**
     *查询未跟酷办公关联的用户总数
     * @return array  用户uid数组
     */
    public function CountUnbind() {
        $list = util\IBOS::app()->db->createCommand()
            ->select('count(uid)')
            ->from('{{user}}')
            ->where("status != " . self::USER_STATUS_ABANDONED . " and uid not in (select uid from {{user_binding}} where app='co' )")->queryColumn();
        return $list;
    }

    /**
     *查询跟酷办公关联但已禁用的用户id总数
     */
    public function CountDelete() {
        $list = util\IBOS::app()->db->createCommand()
            ->select('count(u.uid)')
            ->from('{{user}} u')
            ->leftJoin('{{user_binding}} b', 'u.uid = b.uid')
            ->where("u.status =" . self::USER_STATUS_ABANDONED . " and app='co' ")->queryColumn();
        return $list;
    }

    /**
     *按条件查询未跟酷办公关联的用户id
     * @param  integer $limit
     * @return array  用户uid数组
     */
    public function fetchPartUnbind($start, $length) {
        $list = util\IBOS::app()->db->createCommand()
            ->select('u.uid')
            ->from('{{user}} u')
            ->leftJoin('{{user_binding}} b', 'u.uid = b.uid')
            ->where("b.uid is null")
            ->limit($length, $start)
            ->queryColumn();
        return $list;
    }

}
